home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS03.ADF
/
C
/
kermit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-04-02
|
33KB
|
938 lines
/*
* K e r m i t File Transfer Utility
*
* UNIX Kermit, Columbia University, 1981, 1982, 1983
* Bill Catchings, Bob Cattani, Chris Maio, Frank da Cruz
*
* usage: kermit [csr][dlbe line baud escapechar] [f1 f2 ...]
*
* where c=connect, s=send [files], r=receive, d=debug,
* l=tty line, b=baud rate, e=escape char (decimal ascii code).
* For "host" mode Kermit, format is either "kermit r" to
* receive files, or "kermit s f1 f2 ..." to send f1 .. fn.
*
*
* Fixed up again for Unix, Jim Guyton 7/13/83 (Rand Corp)
*/
/*
* Hacked up for the Amiga, Raymond S. Brand 19851130->
*/
#include <exec/types.h>
#include <stdio.h> /* Standard UNIX definitions */
#include <exec/exec.h>
#include <devices/serial.h>
/* Conditional Compilation: 0 means don't compile it, nonzero means do */
/* Symbol Definitions */
#define MAXPACK 94 /* Maximum packet size */
#define SOH 1 /* Start of header */
#define SP 32 /* ASCII space */
#define CR 13 /* ASCII Carriage Return */
#define DEL 127 /* Delete (rubout) */
#define CTRLD 4
#define BRKCHR CTRLD /* Default escape character for CONNECT */
#define MAXTRY 5 /* Times to retry a packet */
#define MYQUOTE '#' /* Quote character I will use */
#define MYPAD 0 /* Number of padding characters I will need */
#define MYPCHAR 0 /* Padding character I need */
#define MYEOL '\n' /* End-Of-Line character I need */
#define MYTIME 10 /* Seconds after which I should be timed out */
#define MAXTIM 20 /* Maximum timeout interval */
#define MINTIM 2 /* Minumum timeout interval */
/* Global Variables */
int size, /* Size of present data */
n, /* Message number */
rpsiz, /* Maximum receive packet size */
spsiz, /* Maximum send packet size */
pad, /* How much padding to send */
timint, /* Timeout for foreign host on sends */
numtry, /* Times this packet retried */
oldtry, /* Times previous packet retried */
fd, /* File pointer of file to read/write */
image, /* -1 means 8-bit mode */
debug; /* -1 means debugging */
char state, /* Present state of the automaton */
padchar, /* Padding character to send */
eol, /* End-Of-Line character to send */
escchr, /* Connect command escape character */
quote, /* Quote character in incoming data */
*filnam, /* Current file name */
recpkt[MAXPACK], /* Receive packet buffer */
packet[MAXPACK]; /* Packet buffer */
struct IOExtSer SerMsg;
struct MsgPort Serreplyport;
int argc; /* Character pointer for */
char **argv; /* command line arguments */
/*
* m a i n
*
* Main routine - parse command and options, set up the
* serial.device, and dispatch to the appropriate routine.
*/
main(ARGC,ARGV)
int ARGC; /* Character pointer for */
char **ARGV; /* command line arguments */
{
char *cp; /* char pointer */
int speed, cflg, rflg, sflg; /* speed of serial.device */
/* flags for CONNECT, RECEIVE, SEND */
argc = ARGC;
argv = ARGV;
if (argc < 2) usage(); /* Make sure there's a command line. */
cp = *++argv; argv++; argc -= 2; /* Set up pointers to args */
/* Initialize this side's SEND-INIT parameters */
eol = CR; /* EOL for outgoing packets */
quote = MYQUOTE; /* Standard control-quote char "#" */
pad = 0; /* No padding */
padchar = NULL; /* Use null if any padding wanted */
speed = cflg = sflg = rflg = 0; /* Turn off all parse flags */
image = FALSE; /* Default to 7-bit mode */
escchr = BRKCHR; /* Default escape character */
while ((*cp) != NULL) /* Get a character from the cmd line */
switch (*cp++) /* Based on what the character is, */
{ /* do one of the folloing */
case '-': break; /* Ignore dash (UNIX style) */
case 'c': cflg++; break; /* C = CONNECT command */
case 's': sflg++; break; /* S = SEND command */
case 'r': rflg++; break; /* R = RECEIVE command */
case 'e': if (argc--) /* E = specify escape char */
escchr = atoi(*argv++); /* as ascii decimal number */
else usage();
if (debug) fprintf(stderr,"escape char is ascii %d\n",escchr);
break;
case 'b': if (argc--) speed = atoi(*argv++); /* Set baud rate */
else usage();
if (debug) fprintf(stderr,"speed %d\n",speed); break;
case 'i': image = TRUE; break; /* Image (8-bit) mode */
case 'd': debug = TRUE; break; /* Debug mode */
}
/* Done parsing */
if ((cflg+sflg+rflg) != 1) usage(); /* Only one command allowed */
/* Put the serial.device into the correct modes */
Serreplyport.mp_SigBit = AllocSignal(-1);
Serreplyport.mp_SigTask = (struct Task *)(FindTask(0));
Serreplyport.mp_Flags = 0;
SerMsg.io_SerFlags = SERF_XDISABLED | /* SERF_SHARED | */ SERF_RAD_BOOGIE;
OpenDevice(SERIALNAME,0,&SerMsg,0);
if(SerMsg.IOSer.io_Error != 0)
{
printf("\nserial.device open error = %u:\n\n"
,(unsigned)(SerMsg.IOSer.io_Error));
exit(0);
}
SerMsg.IOSer.io_Message.mn_ReplyPort = &Serreplyport;
SerMsg.io_Baud = speed;
SerMsg.io_ReadLen = 8;
SerMsg.io_WriteLen = 8;
SerMsg.io_StopBits = 1;
SerMsg.IOSer.io_Command = SDCMD_SETPARAMS;
DoIO(&SerMsg);
if(SerMsg.IOSer.io_Error != 0)
{
printf("\nserial.device set param error = %u:\n\n"
,(unsigned)(SerMsg.IOSer.io_Error));
CloseDevice(&SerMsg);
exit(0);
}
/* All set up, now execute the command that was given. */
if (cflg) connect(); /* CONNECT command */
if (sflg) /* SEND command */
{
if (argc--) filnam = *argv++; /* Get file to send */
else usage();
if (sendsw() == FALSE) /* Send the file(s) */
printf("Send failed.\n"); /* Report failure */
else /* or */
printf("OK\n"); /* success */
}
if (rflg) /* RECEIVE command */
{
if (recsw() == FALSE) /* Receive the file */
printf("Receive failed.\n"); /* Report failure */
else /* or */
printf("OK\n"); /* success */
}
CloseDevice(&SerMsg);
}
usage() /* Give message if user makes */
{ /* a mistake in the command */
fprintf(stderr,
"Kermit -{{c|s|r}[d][i][b<baud>][e<esc char>]}[ <filename>[ <filename>[..]]]\n");
exit(0);
}
/*
* s e n d s w
*
* Sendsw is the state table switcher for sending
* files. It loops until either it finishes, or
* an error is encountered. The routines called by
* sendsw are responsible for changing the state.
*
*/
sendsw()
{
char sinit(),sfile(),seof(),sdata(),sbreak();
state = 'S'; /* Send initiate is the start state */
n = 0; /* Initialize message number */
numtry = 0; /* Say no tries yet */
while(TRUE) /* Do this as long as necessary */
{
switch(state)
{
case 'D': state = sdata(); break; /* Data-Send state */
case 'F': state = sfile(); break; /* File-Send */
case 'Z': state = seof(); break; /* End-of-File */
case 'S': state = sinit(); break; /* Send-Init */
case 'B': state = sbreak(); break; /* Break-Send */
case 'C': return (TRUE); /* Complete */
case 'A': return (FALSE); /* "Abort" */
default: return (FALSE); /* Unknown, fail */
}
}
}
/*
* s i n i t
*
* Send Initiate: Send my parameters, get other side's back.
*/
char sinit()
{
int num, len; /* Packet number, length */
if (debug) fprintf(stderr,"sinit\n");
if (numtry++ > MAXTRY) return('A'); /* If too many tries, give up */
spar(packet); /* Fill up with init info */
if (debug) fprintf(stderr,"n = %d\n",n);
spack('S',n,6,packet); /* Send an S packet */
switch(rpack(&len,&num,recpkt)) /* What was the reply? */
{
case 'N': return(state); /* NAK */
case 'Y': /* ACK */
if (n != num) return(state); /* If wrong ACK, stay in S state */
rpar(recpkt); /* Get other side's init info */
if (eol == 0) eol = '\n'; /* Check and set defaults */
if (quote == 0) quote = '#'; /* Control-prefix quote */
numtry = 0; /* Reset try counter */
n = (n+1)%64; /* Bump packet count */
if (debug) fprintf(stderr,"Opening %s\n",filnam);
fd = open(filnam,0); /* Open the file to be sent */
if (fd < 0) return('A'); /* if bad file descriptor, give up */
printf("Sending %s\n",filnam);
return('F'); /* OK, switch state to F */
case FALSE: return(state); /* Receive failure, stay in S state */
default: return('A'); /* Anythig else, just "abort" */
}
}
/*
* s f i l e
*
* Send File Header.
*/
char sfile()
{
int num, len; /* Packet number, length */
if (debug) fprintf(stderr,"sfile\n");
if (numtry++ > MAXTRY) return('A'); /* If too many tries, give up */
for (len=0; filnam[len] != '\0'; len++); /* Add up the length */
spack('F',n,len,filnam); /* Send an F packet */
switch(rpack(&len,&num,recpkt)) /* What was the reply? */
{
case 'N': /* NAK, just stay in this state, */
if (n != (num=(--num<0)?63:num)) /* unless NAK for next packet, */
return(state); /* which is just like an ACK */
/* for this packet, fall thru to... */
case 'Y': /* ACK */
if (n != num) return(state); /* If wrong ACK, stay in F state */
numtry = 0; /* Reset try counter */
n = (n+1)%64; /* Bump packet count */
size = bufill(packet); /* Get first data from file */
return('D'); /* Switch state to D */
case FALSE: return(state); /* Receive failure, stay in F state */
default: return('A'); /* Something esle, just "abort" */
}
}
/*
* s d a t a
*
* Send File Data
*/
char sdata()
{
int num, len; /* Packet number, length */
if (numtry++ > MAXTRY) return('A'); /* If too many tries, give up */
spack('D',n,size,packet); /* Send a D packet */
switch(rpack(&len,&num,recpkt)) /* What was the reply? */
{
case 'N': /* NAK, just stay in this state, */
if (n != (num=(--num<0)?63:num)) /* unless NAK for next packet, */
return(state); /* which is just like an ACK */
/* for this packet, fall thru to... */
case 'Y': /* ACK */
if (n != num) return(state); /* If wrong ACK, fail */
numtry = 0; /* Reset try counter */
n = (n+1)%64; /* Bump packet count */
if ((size = bufill(packet)) == EOF) /* Get data from file */
return('Z'); /* If EOF set state to that */
return('D'); /* Got data, stay in state D */
case FALSE: return(state); /* Receive failure, stay in D */
default: return('A'); /* Anything else, "abort" */
}
}
/*
* s e o f
*
* Send End-Of-File.
*/
char seof()
{
int num, len; /* Packet number, length */
if (debug) fprintf(stderr,"seof\n");
if (numtry++ > MAXTRY) return('A'); /* If too many tries, "abort" */
spack('Z',n,0,packet); /* Send a 'Z' packet */
if (debug) fprintf(stderr,"seof1 ");
switch(rpack(&len,&num,recpkt)) /* What was the reply? */
{
case 'N': /* NAK, fail */
if (n != (num=(--num<0)?63:num)) /* ...unless for previous packet, */
return(state); /* in which case, fall thru to ... */
case 'Y': /* ACK */
if (debug) fprintf(stderr,"seof2 ");
if (n != num) return(state); /* If wrong ACK, hold out */
numtry = 0; /* Reset try counter */
n = (n+1)%64; /* and bump packet count */
if (debug) fprintf(stderr,"closing %s, ",filnam);
close(fd); /* Close the input file */
if (debug) fprintf(stderr,"ok, getting next file\n");
if (gnxtfl() == FALSE) /* No more files go? */
return('B'); /* if not, break, EOT, all done */
if (debug) fprintf(stderr,"new file is %s\n",filnam);
fd = open(filnam,0); /* Open next file to send */
if (fd<0) return ('B'); /* if bad file descriptor, give up*/
/* but close file just sent!! */
printf("Sending %s\n",filnam);
return('F'); /* More files, switch state to F */
case FALSE: return(state); /* Receive failure, stay in state Z */
default: return('A'); /* Something else, "abort" */
}
}
/*
* s b r e a k
*
* Send Break (EOT)
*/
char sbreak()
{
int num, len; /* Packet number, length */
if (debug) fprintf(stderr,"sbreak\n");
if (numtry++ > MAXTRY) return('A'); /* If too many tries "abort" */
spack('B',n,0,packet); /* Send a B packet */
switch (rpack(&len,&num,recpkt)) /* What was the reply? */
{
case 'N': /* NAK, fail */
if (n != (num=(--num<0)?63:num)) /* ...unless for previous packet, */
return(state); /* in which case, fall thru to ... */
case 'Y': /* ACK */
if (n != num) return(state); /* If wrong ACK, fail */
numtry = 0; /* Reset try counter */
n = (n+1)%64; /* and bump packet count */
return('C'); /* switch state to Complete */
case FALSE: return(state); /* Receive failure, stay in state B */
default: return ('A'); /* Other, "abort" */
}
}
/*
* r e c s w
*
* This is the state table switcher for receiving files.
*/
recsw()
{
char rinit(),rdata(),rfile(); /* Use these procedures */
state = 'R'; /* Receive is the start state */
n = 0; /* Initialize message number */
numtry = 0; /* Say no tries yet */
while(TRUE) switch(state) /* Do until done */
{
case 'D': state = rdata(); break; /* Data receive state */
case 'F': state = rfile(); break; /* File receive state */
case 'R': state = rinit(); break; /* Send initiate state */
case 'C': return(TRUE); /* Complete state */
case 'A': return(FALSE); /* "Abort" state */
}
}
/*
* r i n i t
*
* Receive Initialization
*/
char rinit()
{
int len, num; /* Packet length, number */
if (numtry++ > MAXTRY) return('A'); /* If too many tries, "abort" */
switch(rpack(&len,&num,packet)) /* Get a packet */
{
case 'S': /* Send-Init */
rpar(packet); /* Get the other side's init data */
spar(packet); /* Fill up packet with my init info */
spack('Y',n,6,packet); /* ACK with my parameters */
oldtry = numtry; /* Save old try count */
numtry = 0; /* Start a new counter */
n = (n+1)%64; /* Bump packet number, mod 64 */
return('F'); /* Enter File-Send state */
case FALSE: return (state); /* Didn't get a packet, keep waiting */
default: return('A'); /* Some other packet type, "abort" */
}
}
/*
* r f i l e
*
* Receive File Header
*/
char rfile()
{
int num, len; /* Packet number, length */
if (numtry++ > MAXTRY) return('A'); /* "abort" if too many tries */
switch(rpack(&len,&num,packet)) /* Get a packet */
{
case 'S': /* Send-Init, maybe our ACK lost */
if (oldtry++ > MAXTRY) return('A'); /* If too many tries, "abort" */
if (num == ((n==0)?63:n-1)) /* Previous packet, mod 64? */
{ /* Yes, ACK it again */
spar(packet); /* with our Send-Init parameters */
spack('Y',num,6,packet); /* ... */
numtry = 0; /* Reset try counter */
return(state); /* Stay in this state */
}
else return('A'); /* Not previous packet, "abort" */
case 'Z': /* End-Of-File */
if (oldtry++ > MAXTRY) return('A');
if (num == ((n==0)?63:n-1)) /* Previous packet, mod 64? */
{ /* Yes, ACK it again. */
spack('Y',num,0,0);
numtry = 0;
return(state); /* Stay in this state */
}
else return('A'); /* Not previous packet, "abort" */
case 'F': /* File Header, */
if (num != n) return('A'); /* which is what we really want */
/* The packet number must be right */
if (!getfil()) /* Try to open a new file */
{
fprintf(stderr,"Could not create %s\n",filnam); /* Give up if can't */
return('A');
}
else /* OK, give message */
printf("Receiving %s\n",packet);
spack('Y',n,0,0); /* Acknowledge the file header */
oldtry = numtry; /* Reset try counters */
numtry = 0; /* ... */
n = (n+1)%64; /* Bump packet number, mod 64 */
return('D'); /* Switch to Data state */
case 'B': /* Break transmission (EOT) */
if (num != n) return ('A'); /* Need right packet number here */
spack('Y',n,0,0); /* Say OK */
return('C'); /* Go to complete state */
case FALSE: return(state); /* Couldn't get packet, keep trying */
default: return ('A'); /* Some other packet, "abort" */
}
}
/*
* r d a t a
*
* Receive Data
*/
char rdata()
{
int num, len; /* Packet number, length */
if (numtry++ > MAXTRY) return('A'); /* "abort" if too many tries */
switch(rpack(&len,&num,packet)) /* Get packet */
{
case 'D': /* Got Data packet */
if (num != n) /* Right packet? */
{ /* No */
if (oldtry++ > MAXTRY) return('A'); /* If too many tries, give up */
if (num == ((n==0)?63:n-1)) /* Else check packet number */
{ /* Previous packet again? */
spack('Y',num,6,packet); /* Yes, re-ACK it */
numtry = 0; /* Reset try counter */
return(state); /* Stay in D, don't write out data! */
}
else return('A'); /* sorry wrong number */
}
/* Got data with right packet number */
bufemp(packet,fd,len); /* Write the data to the file */
spack('Y',n,0,0); /* Acknowledge the packet */
oldtry = numtry; /* Reset the try counters */
numtry = 0; /* ... */
n = (n+1)%64; /* Bump packet number, mod 64 */
return('D'); /* Remain in data state */
case 'F': /* Got a File Header */
if (oldtry++ > MAXTRY) return('A'); /* If too many tries, "abort" */
if (num == ((n==0)?63:n-1)) /* Else check packet number */
{ /* It was the previous one */
spack('Y',num,0,0); /* ACK it again */
numtry = 0; /* Reset try counter */
return(state); /* Stay in Data state */
}
else return('A'); /* Not previous packet, "abort" */
case 'Z': /* End-Of-File */
if (num != n) return('A'); /* Must have right packet number */
spack('Y',n,0,0); /* OK, ACK it. */
close(fd); /* Close the file */
n = (n+1)%64; /* Bump packet number */
return('F'); /* Go back to Receive File state */
case FALSE: return(state); /* No packet came, keep waiting */
default: return('A'); /* Some other packet, "abort" */
}
}
/*
* c o n n e c t
*
* Establish a virtual terminal connection with the remote host.
*
*/
connect()
{
}
/*
* KERMIT utilities.
*/
/* tochar converts a control character to a printable one by adding a space */
char tochar(ch)
char ch;
{
return((char)(ch + ' ')); /* make sure not a control char */
}
/* unchar undoes tochar */
char unchar(ch)
char ch;
{
return((char)(ch - ' ')); /* restore char */
}
/*
* ctl turns a control character into a printable character by toggling the
* control bit (ie. ^A becomes A and A becomes ^A).
*/
char ctl(ch)
char ch;
{
return((char)(ch ^ 64)); /* toggle the control bit */
}
/*
* s p a c k
*
* Send a Packet
*/
spack(type,num,len,data)
char type, *data;
int num, len;
{
int i; /* Character loop counter */
char chksum, buffer[100]; /* Checksum, packet buffer */
register char *bufp; /* Buffer pointer */
bufp = buffer; /* Set up buffer pointer */
for (i=1; i<=pad; i++)
WriteSer(&padchar,1); /* Issue any padding */
*bufp++ = SOH; /* Packet marker, ASCII 1 (SOH) */
chksum = tochar(len+3); /* Initialize the checksum */
*bufp++ = tochar(len+3); /* Send the character count */
chksum = chksum + tochar(num); /* Init checksum */
*bufp++ = tochar(num); /* Packet number */
chksum = chksum + type; /* Accumulate checksum */
*bufp++ = type; /* Packet type */
for (i=0; i<len; i++) /* Loop for all data characters */
{
*bufp++ = data[i]; /* Get a character */
chksum = chksum+data[i]; /* Accumulate checksum */
}
chksum = (chksum + (chksum & 192) / 64) & 63; /* Compute final checksum */
*bufp++ = tochar(chksum); /* Put it in the packet */
*bufp = eol; /* Extra-packet line terminator */
WriteSer(buffer,bufp-buffer+1); /* Send the packet */
if (debug) putc('.',stderr);
}
/*
* r p a c k
*
* Read a Packet
*
*/
rpack(len,num,data)
int *len, *num; /* Packet length, number */
char *data; /* Packet data */
{
int i, done; /* Data character number, loop exit */
char chksum, t, type; /* Checksum, current char, pkt type */
t = '\0';
while (t != SOH) /* Wait for packet header */
{
ReadSer(&t,1);
if (!image) t &= 0177; /* Handle parity */
}
done = FALSE; /* Got SOH, init loop */
while (!done) /* Loop to get a packet */
{
ReadSer(&t,1); /* Get character */
if (!image) t &= 0177; /* Handle parity */
if (t == SOH) continue; /* Resynchronize if SOH */
chksum = t; /* Start the checksum */
*len = unchar(t)-3; /* Character count */
ReadSer(&t,1); /* Get character */
if (!image) t &= 0177; /* Handle parity */
if (t == SOH) continue; /* Resynchronize if SOH */
chksum = chksum + t; /* Accumulate checksum */
*num = unchar(t); /* Packet number */
ReadSer(&t,1); /* Get character */
if (!image) t &= 0177; /* Handle parity */
if (t == SOH) continue; /* Resynchronize if SOH */
chksum = chksum + t; /* Accumulate checksum */
type = t; /* Packet type */
for (i=0; i<*len; i++) /* The data itself, if any */
{ /* Loop for character count */
ReadSer(&t,1); /* Get character */
if (!image) t &= 0177; /* Handle parity */
if (t == SOH) continue; /* Resynch if SOH */
chksum = chksum + t; /* Accumulate checksum */
data[i] = t; /* Put it in the data buffer */
}
data[*len] = 0; /* Mark the end of the data */
ReadSer(&t,1); /* Get last character (checksum) */
if (!image) t &= 0177; /* Handle parity */
if (t == SOH) continue; /* Resynchronize if SOH */
done = TRUE; /* Got checksum, done */
}
chksum = (chksum + (chksum & 192) / 64) & 63; /* Fold bits 7,8 into chksum */
if (chksum != unchar(t)) return(FALSE); /* Check the checksum, fail if bad */
return((int)(type)); /* All OK, return packet type */
}
/*
* b u f i l l
*
* Get a bufferful of data from the file that's being sent.
* Only control-quoting is done; 8-bit & repeat count prefixes are
* not handled.
*/
bufill(buffer)
char buffer[]; /* Buffer */
{
int i; /* Loop index */
char t,t7;
i = 0; /* Init data buffer pointer */
while(read(fd,&t,1) > 0) /* Get the next character */
{
if (image) /* In 8-bit mode? */
{
t7 = t & 0177; /* Yes, look at low-order 7 bits */
if (t7 < SP || t7==DEL || t7==quote) /* Control character? */
{ /* Yes, */
buffer[i++] = quote; /* quote this character */
if (t7 != quote) t = ctl(t); /* and uncontrollify */
}
}
else /* Else, ASCII text mode */
{
t &= 0177; /* Strip off the parity bit */
if (t < SP || t == DEL || t == quote) /* Control character? */
{ /* Yes */
if (t=='\n') /* If newline, squeeze CR in first */
{
buffer[i++] = quote;
buffer[i++] = ctl('\r');
}
buffer[i++] = quote; /* Insert quote */
if (t != quote) t=ctl(t); /* Uncontrollified the character */
}
}
buffer[i++] = t; /* Deposit the character itself */
if (i >= spsiz-8) return(i); /* Check length */
}
if (i==0) return(EOF); /* Wind up here only on EOF */
return(i); /* Handle partial buffer */
}
/*
* b u f e m p
*
* Get data from an incoming packet into a file.
*/
bufemp(buffer,fd,len)
char buffer[]; /* Buffer */
int fd, len; /* File pointer, length */
{
int i; /* Counter */
char t; /* Character holder */
for (i=0; i<len; i++) /* Loop thru the data field */
{
t = buffer[i]; /* Get character */
if (t == MYQUOTE) /* Control quote? */
{ /* Yes */
t = buffer[++i]; /* Get the quoted character */
if ((t & 0177) != MYQUOTE) /* Low order bits match quote char? */
t = ctl(t); /* No, uncontrollify it */
}
if (image || (t != CR)) /* Don't pass CR in text mode */
write(fd,&t,1); /* Put the char in the file */
}
}
/*
* g e t f i l
*
* Open a new file
*/
getfil()
{
if (gnxtfl() == FALSE) filnam = packet;
fd = creat(filnam,0644);
return (fd > 0); /* Return false if file won't open */
}
/*
* g n x t f l
*
* Get next file in a file group
*/
gnxtfl()
{
if (debug) fprintf(stderr, "gnxtfl\n");
if (argc--) filnam = *argv++;
else return FALSE; /* If no more, fail */
return TRUE; /* else succeed */
}
/*
* s p a r
*
* Fill the data array with my send-init parameters
*
*/
spar(data)
char data[];
{
data[0] = tochar(MAXPACK); /* Biggest packet I can receive */
data[1] = tochar(MYTIME); /* When I want to be timed out */
data[2] = tochar(MYPAD); /* How much padding I need */
data[3] = ctl(MYPCHAR); /* Padding character I want */
data[4] = tochar(MYEOL); /* End-Of-Line character I want */
data[5] = MYQUOTE; /* Control-Quote character I send */
}
/* r p a r
*
* Get the other host's send-init parameters
*
*/
rpar(data)
char data[];
{
spsiz = unchar(data[0]); /* Maximum send packet size */
timint = unchar(data[1]); /* When I should time out */
pad = unchar(data[2]); /* Number of pads to send */
padchar = ctl(data[3]); /* Padding character to send */
eol = unchar(data[4]); /* EOL character I must send */
quote = data[5]; /* Incoming data quote character */
}
/* R e a d S e r
*
* Read characters from the serial.device
*
*/
ReadSer(data,length)
char *data;
int length;
{
SerMsg.IOSer.io_Command = CMD_READ;
SerMsg.IOSer.io_Flags = NULL;
SerMsg.IOSer.io_Length = length;
SerMsg.IOSer.io_Data = (APTR)(data);
SendIO(&SerMsg);
WaitIO(&SerMsg);
if(SerMsg.IOSer.io_Error != 0)
{
printf("\nserial.device read error = %u:\n\n"
,(unsigned)(SerMsg.IOSer.io_Error));
CloseDevice(&SerMsg);
exit(0);
}
}
/* W r i t e S e r
*
* Write characters to the serial.device
*
*/
WriteSer(data,length)
char *data;
int length;
{
SerMsg.IOSer.io_Command = CMD_WRITE;
SerMsg.IOSer.io_Flags = NULL;
SerMsg.IOSer.io_Length = length;
SerMsg.IOSer.io_Data = (APTR)(data);
SendIO(&SerMsg);
WaitIO(&SerMsg);
if(SerMsg.IOSer.io_Error != 0)
{
printf("\nserial.device write error = %u:\n\n"
,(unsigned)(SerMsg.IOSer.io_Error));
CloseDevice(&SerMsg);
exit(0);
}
}